{{ $kdsGlobalServerTLSSecretName := "" }}
{{ if eq .Values.controlPlane.mode "global" }}
  {{ $kdsGlobalServerTLSSecretName = .Values.controlPlane.tls.kdsGlobalServer.secretName }}
  {{ if and .Values.controlPlane.tls.kdsGlobalServer.create (not $kdsGlobalServerTLSSecretName) }}
    {{ $kdsGlobalServerTLSSecretName = print (include "kuma.name" .) "-kds-global-server-tls" }}
  {{ end }}
{{ end }}

{{ $kdsZoneClientTLSSecretName := "" }}
{{ if eq .Values.controlPlane.mode "zone" }}
  {{ $kdsZoneClientTLSSecretName = .Values.controlPlane.tls.kdsZoneClient.secretName }}
  {{ if and .Values.controlPlane.tls.kdsZoneClient.create (not $kdsZoneClientTLSSecretName) }}
    {{ $kdsZoneClientTLSSecretName = print (include "kuma.name" .) "-kds-zone-client-tls" }}
  {{ end }}
{{ end }}

{{ if not (or (eq .Values.controlPlane.mode "zone") (eq .Values.controlPlane.mode "global") (eq .Values.controlPlane.mode "standalone")) }}
  {{ $msg := printf "controlPlane.mode invalid got:'%s' supported values: global,zone,standalone" .Values.controlPlane.mode }}
  {{ fail $msg }}
{{ end }}
{{ if eq .Values.controlPlane.mode "zone" }}
  {{ if not (empty .Values.controlPlane.zone) }}
    {{ if gt (len .Values.controlPlane.zone) 253 }}
      {{ fail "controlPlane.zone must be no more than 253 characters" }}
    {{ else }}
      {{ if not (regexMatch "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" .Values.controlPlane.zone) }}
        {{ fail "controlPlane.zone must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character" }}
      {{ end }}
    {{ end }}
  {{ end }}
  {{ if not (empty .Values.controlPlane.kdsGlobalAddress) }}
    {{ $url := urlParse .Values.controlPlane.kdsGlobalAddress }}
    {{ if not (or (eq $url.scheme "grpcs") (eq $url.scheme "grpc")) }}
      {{ $msg := printf "controlPlane.kdsGlobalAddress must be a url with scheme grpcs:// or grpc:// got:'%s'" .Values.controlPlane.kdsGlobalAddress }}
      {{ fail $msg }}
    {{ end }}
  {{ end }}
{{ else }}
  {{ if not (empty .Values.controlPlane.zone) }}
    {{ fail "Can't specify a controlPlane.zone when controlPlane.mode!='zone'" }}
  {{ end }}
  {{ if not (empty .Values.controlPlane.kdsGlobalAddress) }}
    {{ fail "Can't specify a controlPlane.kdsGlobalAddress when controlPlane.mode!='zone'" }}
  {{ end }}
{{ end }}

{{- $defaultEnv := include "kuma.defaultEnv" . | fromYaml | pluck "env" | first }}
{{- if eq .Values.controlPlane.environment "universal" }}
{{- $defaultEnv = include "kuma.universal.defaultEnv" . | fromYaml | pluck "env" | first }}
{{- end }}
{{- $defaultEnvDict := dict }}
{{- range $index, $item := $defaultEnv }}
{{- $name := $item.name | upper }}
{{- $defaultEnvDict := set $defaultEnvDict $name $item.value }}
{{- end }}
{{- $envVarsCopy := deepCopy .Values.controlPlane.envVars }}
{{- $mergedEnv := merge $envVarsCopy $defaultEnvDict }}
{{- $defaultSecrets := include "kuma.parentSecrets" . | fromYaml }}
{{- $extraSecrets := .Values.controlPlane.extraSecrets }}
{{- $mergedSecrets := merge $extraSecrets $defaultSecrets }}

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "kuma.name" . }}-control-plane
  namespace: {{ .Release.Namespace }}
  labels: {{ include "kuma.cpLabels" . | nindent 4 }}
  annotations: {{ include "kuma.cpDeploymentAnnotations" . | nindent 4 }}
spec:
  {{- if not .Values.controlPlane.autoscaling.enabled }}
  replicas: {{ .Values.controlPlane.replicas }}
  {{- end }}
  minReadySeconds: {{ .Values.controlPlane.minReadySeconds }}
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      {{- include "kuma.selectorLabels" . | nindent 6 }}
      app: {{ include "kuma.name" . }}-control-plane
  template:
    metadata:
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/cp-configmap.yaml") . | sha256sum }}
        {{- if .Values.restartOnSecretChange }}
        checksum/tls-secrets: {{ include (print $.Template.BasePath "/cp-webhooks-and-secrets.yaml") . | sha256sum }}
        {{- end }}
        {{- range $key, $value := $.Values.controlPlane.podAnnotations }}
        {{ $key }}: {{ $value | quote }}
        {{- end }}
      labels: {{ include "kuma.cpLabels" . | nindent 8 }}
    spec:
      {{- with .Values.controlPlane.affinity }}
      affinity: {{ tpl (toYaml . | nindent 8) $ }}
      {{- end }}
      {{- with .Values.controlPlane.topologySpreadConstraints }}
      topologySpreadConstraints: {{ tpl (toYaml . | nindent 8) $ }}
      {{- end }}
      securityContext:
      {{- toYaml .Values.controlPlane.podSecurityContext | trim | nindent 8 }}
      serviceAccountName: {{ include "kuma.name" . }}-control-plane
      automountServiceAccountToken: {{ .Values.controlPlane.automountServiceAccountToken }}
      {{- with .Values.controlPlane.nodeSelector }}
      nodeSelector:
        {{ toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.controlPlane.tolerations }}
      tolerations:
      {{ toYaml . | nindent 8 }}
      {{- end }}
      hostNetwork: {{ .Values.controlPlane.hostNetwork }}
      terminationGracePeriodSeconds: {{ .Values.controlPlane.terminationGracePeriodSeconds }}
      {{- if (eq .Values.controlPlane.environment "universal") }}
      initContainers:
        - name: migration
          image: {{ include "kuma.formatImage" (dict "image" .Values.controlPlane.image "root" $) | quote }}
          imagePullPolicy: {{ .Values.controlPlane.image.pullPolicy }}
          securityContext:
          {{- toYaml .Values.controlPlane.containerSecurityContext | trim | nindent 12 }}
          env:
            {{- range $key, $value := $mergedEnv }}
            - name: {{ $key }}
              value: {{ $value | quote }}
            {{- end }}
            {{- range $element := .Values.controlPlane.secrets }}
            - name: {{ $element.Env }}
              valueFrom:
                secretKeyRef:
                  name: {{ $element.Secret }}
                  key: {{ $element.Key }}
          {{- end }}
          args:
            - migrate
            - up
            - --log-level=info
            - --config-file=/etc/kuma.io/kuma-control-plane/config.yaml
          resources:
            {{- if .Values.controlPlane.resources }}
            {{- .Values.controlPlane.resources | toYaml | nindent 12 }}
            {{- end }}
          volumeMounts:
          {{- if .Values.postgres.tls.caSecretName }}
            - name: postgres-tls-cert-ca
              subPath: ca.crt
              mountPath: /var/run/secrets/kuma.io/postgres-tls-cert/ca.crt
              readOnly: true
          {{- end }}
          {{- if .Values.postgres.tls.secretName }}
            - name: postgres-tls-cert
              subPath: tls.crt
              mountPath: /var/run/secrets/kuma.io/postgres-tls-cert/tls.crt
              readOnly: true
            - name: postgres-tls-cert
              subPath: tls.key
              mountPath: /var/run/secrets/kuma.io/postgres-tls-cert/tls.key
              readOnly: true
          {{- end }}
            - name: {{ include "kuma.name" . }}-control-plane-config
              mountPath: /etc/kuma.io/kuma-control-plane
              readOnly: true
      {{- end }}
      containers:
        - name: control-plane
          image: {{ include "kuma.formatImage" (dict "image" .Values.controlPlane.image "root" $) | quote }}
          imagePullPolicy: {{ .Values.controlPlane.image.pullPolicy }}
          securityContext:
          {{- toYaml .Values.controlPlane.containerSecurityContext | trim | nindent 12 }}
          env:
          {{- range $key, $value := $mergedEnv }}
            - name: {{ $key }}
              value: {{ $value | quote }}
          {{- end }}
          {{- range $element := .Values.controlPlane.secrets }}
            - name: {{ $element.Env }}
              valueFrom:
                secretKeyRef:
                  name: {{ $element.Secret }}
                  key: {{ $element.Key }}
          {{- end }}
            - name: KUMA_INTER_CP_CATALOG_INSTANCE_ADDRESS
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
          args:
            - run
            - --log-level={{ .Values.controlPlane.logLevel }}
            - --log-output-path={{ .Values.controlPlane.logOutputPath }}
            - --config-file=/etc/kuma.io/kuma-control-plane/config.yaml
          ports:
            - containerPort: 5680
              name: diagnostics
              protocol: TCP
            - containerPort: 5681
            - containerPort: 5682
            - containerPort: {{ .Values.controlPlane.admissionServerPort | default "5443" }}
            {{- if ne .Values.controlPlane.mode "global" }}
            - containerPort: 5678
            {{- end }}
          livenessProbe:
            timeoutSeconds: 10
            httpGet:
              path: /healthy
              port: 5680
          readinessProbe:
            timeoutSeconds: 10
            httpGet:
              path: /ready
              port: 5680
          resources:
            {{- if .Values.controlPlane.resources }}
            {{- .Values.controlPlane.resources | toYaml | nindent 12 }}
            {{- end }}
          {{ with .Values.controlPlane.lifecycle }}
          lifecycle: {{ . | toYaml | nindent 14 }}
          {{ end }}
          volumeMounts:
          {{- if eq .Values.controlPlane.environment "kubernetes" }}
          {{- if not .Values.controlPlane.automountServiceAccountToken }}
            - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
              name: serviceaccount-token
              readOnly: true
          {{- end }}
            - name: general-tls-cert
              mountPath: /var/run/secrets/kuma.io/tls-cert/tls.crt
              subPath: tls.crt
              readOnly: true
            - name: general-tls-cert
              mountPath: /var/run/secrets/kuma.io/tls-cert/tls.key
              subPath: tls.key
              readOnly: true
            - name: general-tls-cert{{- if .Values.controlPlane.tls.general.caSecretName }}-ca{{- end }}
              mountPath: /var/run/secrets/kuma.io/tls-cert/ca.crt
              subPath: ca.crt
              readOnly: true
          {{- end }}
          {{- if and (eq .Values.controlPlane.environment "universal") (eq .Values.controlPlane.mode "zone") }}
            {{- if .Values.controlPlane.tls.general.secretName }}
            - name: general-tls-cert
              mountPath: /var/run/secrets/kuma.io/tls-cert/tls.crt
              subPath: tls.crt
              readOnly: true
            - name: general-tls-cert
              mountPath: /var/run/secrets/kuma.io/tls-cert/tls.key
              subPath: tls.key
              readOnly: true
            - name: general-tls-cert{{- if .Values.controlPlane.tls.general.caSecretName }}-ca{{- end }}
              mountPath: /var/run/secrets/kuma.io/tls-cert/ca.crt
              subPath: ca.crt
              readOnly: true
            {{- end }}
          {{- end }}
            - name: {{ include "kuma.name" . }}-control-plane-config
              mountPath: /etc/kuma.io/kuma-control-plane
              readOnly: true
          {{- if .Values.controlPlane.tls.apiServer.secretName }}
            - name: api-server-tls-cert
              mountPath: /var/run/secrets/kuma.io/api-server-tls-cert
              readOnly: true
          {{- end }}
          {{- if .Values.postgres.tls.caSecretName }}
            - name: postgres-tls-cert-ca
              subPath: ca.crt
              mountPath: /var/run/secrets/kuma.io/postgres-tls-cert/ca.crt
              readOnly: true
          {{- end }}
          {{- if .Values.postgres.tls.secretName }}
            - name: postgres-tls-cert
              subPath: tls.crt
              mountPath: /var/run/secrets/kuma.io/postgres-tls-cert/tls.crt
              readOnly: true
            - name: postgres-tls-cert
              subPath: tls.key
              mountPath: /var/run/secrets/kuma.io/postgres-tls-cert/tls.key
              readOnly: true
          {{- end }}
          {{- if .Values.controlPlane.tls.apiServer.clientCertsSecretName }}
            - name: api-server-client-certs
              mountPath: /var/run/secrets/kuma.io/api-server-client-certs
              readOnly: true
          {{- end }}
          {{- if $kdsGlobalServerTLSSecretName }}
            - name: kds-server-tls-cert
              mountPath: /var/run/secrets/kuma.io/kds-server-tls-cert
              readOnly: true
          {{- end }}
          {{- if $kdsZoneClientTLSSecretName }}
            - name: kds-client-tls-cert
              mountPath: /var/run/secrets/kuma.io/kds-client-tls-cert
              readOnly: true
          {{- end }}
          {{- range $extraConfigMap := .Values.controlPlane.extraConfigMaps }}
            - name: {{ $extraConfigMap.name }}
              mountPath: {{ $extraConfigMap.mountPath }}
              readOnly: {{ $extraConfigMap.readOnly }}
          {{- end }}
          {{- range $mergedSecret := $mergedSecrets }}
            - name: {{ $mergedSecret.name }}
              mountPath: {{ $mergedSecret.mountPath }}
              subPath: {{ $mergedSecret.subPath }}
              readOnly: {{ $mergedSecret.readOnly }}
          {{- end }}
            - name: tmp
              mountPath: /tmp
      volumes:
      {{- if eq .Values.controlPlane.environment "kubernetes" }}
        {{- if not .Values.controlPlane.automountServiceAccountToken }}
        - name: serviceaccount-token
          projected:
            defaultMode: 420
            sources:
            - serviceAccountToken:
                 expirationSeconds: 3600
                 path: token
            - configMap:
                 name: kube-root-ca.crt
                 items:
                   - key: ca.crt
                     path: ca.crt
            - downwardAPI:
                 items:
                   - fieldRef:
                        apiVersion: v1
                        fieldPath: metadata.namespace
                     path: namespace
        {{- end }}
        {{- if .Values.controlPlane.tls.general.secretName }}
        - name: general-tls-cert
          secret:
            secretName: {{ .Values.controlPlane.tls.general.secretName }}
        {{- else }}
        - name: general-tls-cert
          secret:
            secretName: {{ include "kuma.name" . }}-tls-cert
        {{- end }}
        {{- if .Values.controlPlane.tls.general.caSecretName }}
        - name: general-tls-cert-ca
          secret:
            secretName: {{ .Values.controlPlane.tls.general.caSecretName }}
        {{- end }}
      {{- end }}
      {{- if and (eq .Values.controlPlane.environment "universal") (eq .Values.controlPlane.mode "zone") }}
        {{- if .Values.controlPlane.tls.general.secretName }}
        - name: general-tls-cert
          secret:
            secretName: {{ .Values.controlPlane.tls.general.secretName }}
        {{- end }}
        {{- if .Values.controlPlane.tls.general.caSecretName }}
        - name: general-tls-cert-ca
          secret:
            secretName: {{ .Values.controlPlane.tls.general.caSecretName }}
        {{- end }}
      {{- end }}
        {{- if .Values.controlPlane.tls.apiServer.secretName }}
        - name: api-server-tls-cert
          secret:
            secretName: {{ .Values.controlPlane.tls.apiServer.secretName }}
        {{- end }}
        {{- if .Values.postgres.tls.caSecretName }}
        - name: postgres-tls-cert-ca
          secret:
            secretName: {{ .Values.postgres.tls.caSecretName }}
        {{- end }}
        {{- if .Values.postgres.tls.secretName }}
        - name: postgres-tls-cert
          secret:
            secretName: {{ .Values.postgres.tls.secretName }}
        {{- end }}
        {{- if .Values.controlPlane.tls.apiServer.clientCertsSecretName }}
        - name: api-server-client-certs
          secret:
            secretName: {{ .Values.controlPlane.tls.apiServer.clientCertsSecretName }}
        {{- end }}
        {{- if $kdsGlobalServerTLSSecretName }}
        - name: kds-server-tls-cert
          secret:
            secretName: {{ $kdsGlobalServerTLSSecretName }}
        {{- end }}
        {{- if $kdsZoneClientTLSSecretName }}
        - name: kds-client-tls-cert
          secret:
            secretName: {{ $kdsZoneClientTLSSecretName }}
        {{- end }}
        - name: {{ include "kuma.name" . }}-control-plane-config
          configMap:
            name: {{ include "kuma.name" . }}-control-plane-config
        {{- range $extraConfigMap := .Values.controlPlane.extraConfigMaps }}
        - name: {{ $extraConfigMap.name }}
          configMap:
            name: {{ $extraConfigMap.name }}
        {{- end }}
        {{- range $mergedSecret := $mergedSecrets }}
        - name: {{ $mergedSecret.name }}
          secret:
            secretName: {{ $mergedSecret.name }}
        {{- end }}
        - name: tmp
          emptyDir: {}
